#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "linuxlist.h"
#include <stdint.h>

#define HANDLE void*
#define BOOL int

#define MAX_EVENT_NUMS  (7)
#define LocalAlloc(x, size) malloc(size)
#define LocalFree(p) free(p)
#define SecureZeroMemory(ptr, size) memset(ptr, 0, size)

struct Event
{
    struct list_head entry;
    HANDLE handle;
    BOOL manualReset;
    BOOL initialState;
	char name[32];
};


struct EventPool
{
    struct list_head list;
    uint32_t allNums; //最大event数
    uint32_t usedNums;//使用中的event数
};

struct EventPool ePool;
int ghandle = 1;


HANDLE CreateEvent(void* arg, BOOL mreset, BOOL initState, char *name)
{
	return (HANDLE)&ghandle;
}

int CreateEventPool(uint32_t nums) 
{
    int i;
    struct Event * evt = NULL;
    
	INIT_LIST_HEAD(&ePool.list);
    nums = (MAX_EVENT_NUMS < nums) ? (MAX_EVENT_NUMS) : nums;
    ePool.allNums = nums;
    ePool.usedNums = 0;
    for (i=0; i<nums; i++) {
        evt = (struct Event*)LocalAlloc(LMEM_ZEROINIT, sizeof(struct Event));
		if (evt == NULL) {
			perror("malloc error\n");
		}
        SecureZeroMemory(evt, sizeof(struct Event));
        list_add_tail(&evt->entry, &ePool.list);
    }
    return 0;
}

void ReleaseEventPool(void) 
{
    struct Event *evt;
    list_for_each_entry(evt, &ePool.list, entry) {
        LocalFree(evt);
    }
    ePool.usedNums = 0;
    ePool.allNums  = 0;
}



struct Event* EventCreate(BOOL manualReset, BOOL initialState)
{
    char evtName[32] = {0};
    struct Event *evt, *idleEvt = NULL;
    int isFound = 0, isIdle = 0, isNotexist = 0;
    if (ePool.usedNums >= MAX_EVENT_NUMS) {
		printf("max\r\n");
        return NULL;
    }

    
//    if (ePool.usedNums) { //查找未使用的event
        list_for_each_entry(evt, &ePool.list, entry) { 
            if (evt->handle) {//已创建
                if ((evt->manualReset == manualReset) 
                    && (evt->manualReset == manualReset)) {
                    isFound = 1;
                    list_del_init(&evt->entry);
                    break;
                }
            } else {
                idleEvt = evt;
            }
        }    
  //  }
    if (!isFound) {
        sprintf(evtName, "epoolitem%d", ePool.usedNums++);
        if (idleEvt) { //有空闲event未使用
            evt = idleEvt;
			isIdle = 1;
			list_del_init(&evt->entry);
        } else {
			isNotexist = 1;
			if (ePool.allNums >= MAX_EVENT_NUMS) {
				return NULL;
			}
            evt = (struct Event*)LocalAlloc(LMEM_ZEROINIT, sizeof(struct Event));
            SecureZeroMemory(evt, sizeof(struct Event));
			ePool.allNums++;
        }
        evt->handle = CreateEvent( NULL, manualReset, initialState, evtName);    
		strcpy(evt->name, evtName);
        evt->manualReset = manualReset;
        evt->initialState = initialState;
    }
	printf("%s reset:%d initstate:%d usedNums:%d allNums:%d isFound:%d isIdle:%d isNotexist:%d\n", 
		evt->name, evt->manualReset, evt->initialState, ePool.usedNums,ePool.allNums, 
		isFound, isIdle, isNotexist);
    return evt;
}

void EventDelete(struct Event *evt)
{
    list_add_tail(&evt->entry, &ePool.list);
}


int main(void)
{
	struct Event *evt[20];
	CreateEventPool(5);
	evt[0] = EventCreate(0,1);
	evt[1] = EventCreate(0,1);
	evt[2] = EventCreate(0,1);
	EventDelete(evt[2]);
	evt[3] = EventCreate(0,1);
	EventDelete(evt[3]);
	evt[4] = EventCreate(1,1);
	evt[5] = EventCreate(1,1);
	EventDelete(evt[5]);
	evt[7] = EventCreate(1,1);
	EventDelete(evt[7]);
	evt[8] = EventCreate(1,1);
	EventDelete(evt[8]);
	evt[9] = EventCreate(0,1);
	evt[10] = EventCreate(0,1);
	evt[11] = EventCreate(0,1);
	evt[12] = EventCreate(0,1);
	evt[13] = EventCreate(0,1);
	return 0;
}
